import os
import subprocess
import chardet  # 需要安装：pip install chardet

# 使用时在有备份文件的电脑执行恢复，先把backups中没用的文件删除，只留需要恢复的文件，下面host为目标电脑
# 配置数据库连接信息
DB_CONFIG = {
    'host': '10.114.183.17',
    # 'host': 'localhost',
    'port': '3306',
    'user': 'labuser',
    'password': '123456',
}

# 配置备份文件存储路径（恢复源路径）
BACKUP_DIR = os.path.join('C:\\', 'backups')

def detect_encoding(file_path):
    """检测文件编码"""
    try:
        with open(file_path, 'rb') as f:
            result = chardet.detect(f.read(10000))
        return result['encoding']
    except Exception as e:
        print(f"编码检测失败: {e}")
        return None

def restore_database():
    """从备份文件恢复所有数据库"""
    sql_files = [f for f in os.listdir(BACKUP_DIR) if f.endswith('.sql')]
    
    if not sql_files:
        print("未找到SQL备份文件")
        return
    
    print(f"找到 {len(sql_files)} 个备份文件")
    
    for filename in sql_files:
        try:
            db_name = filename.split('_', 1)[0]  # 提取数据库名
            file_path = os.path.join(BACKUP_DIR, filename)
            
            print(f"正在恢复 {db_name} 数据库...")
            
            # 检测文件编码
            encoding = detect_encoding(file_path)
            if encoding and 'utf-8' not in encoding.lower():
                print(f"警告: 文件 {filename} 编码为 {encoding}，可能存在问题")
            
            # 执行恢复命令，使用 --default-character-set=latin1
            cmd = [
                'mysql',
                '--default-character-set=latin1',  # 使用latin1避免解码错误
                f"--host={DB_CONFIG['host']}",
                f"--port={DB_CONFIG['port']}",
                f"--user={DB_CONFIG['user']}",
                f"--password={DB_CONFIG['password']}",
                db_name
            ]
            
            # 不预处理文件，直接使用原文件
            with open(file_path, 'r', encoding='latin1') as f:  # 使用latin1编码读取
                result = subprocess.run(
                    cmd, 
                    stdin=f, 
                    capture_output=True, 
                    text=True,
                    check=True
                )
            
            print(f"✓ {db_name} 恢复成功")
            
        except subprocess.CalledProcessError as e:
            print(f"✗ {filename} 恢复失败: {e.stderr.strip()}")
            # 保存调试文件
            temp_file = os.path.join(BACKUP_DIR, f"temp_{filename}")
            with open(file_path, 'r', encoding='latin1', errors='ignore') as f_in:
                content = f_in.read(20000)  # 读取前20000个字符
                with open(temp_file, 'w', encoding='utf-8') as f_out:
                    f_out.write(content)
            print(f"调试文件已保存至: {temp_file}")
        except Exception as e:
            print(f"✗ {filename} 恢复失败: {str(e)}")

if __name__ == "__main__":
    print(f"开始从 {BACKUP_DIR} 恢复数据库...")
    input("按回车键继续...")  # 简单确认
    restore_database()
    print("恢复完成") 